package com.eduagent.xwqeduagent.api.RealTimeVoiceToTextConversion.sample;

import com.eduagent.xwqeduagent.api.RealTimeVoiceToTextConversion.constant.RealTimeASRConstant;
import com.eduagent.xwqeduagent.api.RealTimeVoiceToTextConversion.model.ASRParams;
import com.eduagent.xwqeduagent.api.RealTimeVoiceToTextConversion.model.ASRResult;
import com.eduagent.xwqeduagent.api.RealTimeVoiceToTextConversion.service.RealTimeASRService;
import com.eduagent.xwqeduagent.api.RealTimeVoiceToTextConversion.service.RealTimeASRService.ASRCallback;
import com.eduagent.xwqeduagent.api.RealTimeVoiceToTextConversion.util.AuthUtil;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.concurrent.CountDownLatch;

/**
 * 实时语音转写API示例程序
 */
public class RealTimeASRDemo {
    
    // 设置讯飞开放平台的API凭证（使用您自己的凭据）
    private static final String APP_ID = "637d1630";
    // API密钥 (对应讯飞开放平台的APISecret)
    private static final String API_KEY = "a64e46d959522759bf70a7d3e7c35b8f";
    
    public static void main(String[] args) {
        try {
            // 初始化API凭证
            RealTimeASRConstant.APP_ID = APP_ID;
            RealTimeASRConstant.API_KEY = API_KEY;
            
            // 打印配置信息
            RealTimeASRConstant.printConfig();
            
            // 测试签名生成
            try {
                String ts = String.valueOf(System.currentTimeMillis() / 1000);
                String signature = AuthUtil.generateSignature(RealTimeASRConstant.APP_ID, ts);
                System.out.println("测试签名生成: 时间戳=" + ts + ", 签名=" + signature);
            } catch (Exception e) {
                System.err.println("测试签名生成失败: " + e.getMessage());
                e.printStackTrace();
            }
            
            // 创建服务实例
            RealTimeASRService service = new RealTimeASRService();
            
            // 检查音频文件是否存在
            String audioFilePath = "src/main/resources/audio/test_1.pcm";
            File audioFile = new File(audioFilePath);
            if (!audioFile.exists()) {
                System.err.println("警告: 音频文件不存在: " + audioFilePath);
                System.err.println("创建一个测试目录...");
                
                // 创建目录
                File audioDir = new File("src/main/resources/audio");
                if (!audioDir.exists()) {
                    audioDir.mkdirs();
                    System.out.println("已创建音频目录: " + audioDir.getAbsolutePath());
                }
                
                System.err.println("请在下次运行前准备一个16k采样率的PCM音频文件放置在: " + audioFile.getAbsolutePath());
            } else {
                System.out.println("音频文件存在: " + audioFile.getAbsolutePath() + ", 大小: " + audioFile.length() + " 字节");
            }
            
            // 执行同步识别示例
            System.out.println("===== 同步识别示例 =====");
            syncRecognitionDemo(service);
            
            // 执行异步识别示例
            System.out.println("\n===== 异步识别示例 =====");
            asyncRecognitionDemo(service);
            
        } catch (Exception e) {
            System.err.println("示例运行失败: " + e.getMessage());
            e.printStackTrace();
        }
    }
    
    /**
     * 同步识别示例
     * 
     * @param service 实时语音转写服务
     * @throws Exception 识别过程中的异常
     */
    private static void syncRecognitionDemo(RealTimeASRService service) throws Exception {
        // 读取音频文件（假设在resources目录下有一个16k采样率的PCM音频文件）
        String audioFilePath = "src/main/resources/audio/test_1.pcm";
        byte[] audioData = readAudioFile(audioFilePath);
        
        if (audioData == null) {
            System.err.println("未找到音频文件: " + audioFilePath);
            System.err.println("请准备一个16k采样率的PCM音频文件进行测试");
            return;
        }
        
        // 设置业务参数
        ASRParams params = ASRParams.builder()
                .lang(RealTimeASRConstant.LANG_CHINESE)
                .pd(RealTimeASRConstant.PD_EDU)  // 使用教育领域模型
                .punc("1")  // 启用标点符号
                .engLangType(RealTimeASRConstant.ENG_LANG_AUTO)  // 自动中英文模式
                .build();
        
        System.out.println("开始识别音频...");
        long startTime = System.currentTimeMillis();
        
        // 执行同步识别
        String result = service.recognizeSpeech(audioData, params);
        
        long endTime = System.currentTimeMillis();
        System.out.println("识别完成，耗时: " + (endTime - startTime) + "ms");
        System.out.println("识别结果: " + result);
    }
    
    /**
     * 异步识别示例
     * 
     * @param service 实时语音转写服务
     * @throws Exception 识别过程中的异常
     */
    private static void asyncRecognitionDemo(RealTimeASRService service) throws Exception {
        // 读取音频文件（假设在resources目录下有一个16k采样率的PCM音频文件）
        String audioFilePath = "src/main/resources/audio/test_1.pcm";
        byte[] audioData = readAudioFile(audioFilePath);
        
        if (audioData == null) {
            System.err.println("未找到音频文件: " + audioFilePath);
            System.err.println("请准备一个16k采样率的PCM音频文件进行测试");
            return;
        }
        
        // 设置业务参数
        ASRParams params = ASRParams.builder()
                .lang(RealTimeASRConstant.LANG_CHINESE)
                .pd(RealTimeASRConstant.PD_EDU)  // 使用教育领域模型
                .punc("1")  // 启用标点符号
                .engLangType(RealTimeASRConstant.ENG_LANG_AUTO)  // 自动中英文模式
                // 添加翻译功能示例
                .transType("normal")
                .transStrategy(2)  // 返回中间过程中的结果
                .targetLang("en")  // 翻译为英文
                .build();
        
        System.out.println("开始异步识别音频...");
        long startTime = System.currentTimeMillis();
        
        // 用于等待异步识别完成
        CountDownLatch latch = new CountDownLatch(1);
        
        // 创建回调
        ASRCallback callback = new ASRCallback() {
            @Override
            public void onConnected(String sessionId) {
                System.out.println("WebSocket连接已建立，会话ID: " + sessionId);
                
                // 分块发送音频数据
                try {
                    int frameSize = RealTimeASRConstant.DEFAULT_FRAME_SIZE;
                    for (int i = 0; i < audioData.length; i += frameSize) {
                        int length = Math.min(frameSize, audioData.length - i);
                        byte[] frame = new byte[length];
                        System.arraycopy(audioData, i, frame, 0, length);
                        service.sendAudioData(frame);
                        
                        // 控制发送速率，模拟实时发送
                        Thread.sleep(40);
                    }
                    
                    // 发送结束标志
                    service.sendEndSignal();
                    System.out.println("音频数据发送完成，等待转写结果...");
                } catch (Exception e) {
                    System.err.println("发送音频数据失败: " + e.getMessage());
                    latch.countDown();
                }
            }
            
            @Override
            public void onResult(ASRResult result) {
                if (result.isTranslation()) {
                    System.out.println("翻译结果: " + result.getPlainText() + 
                            (result.getTranslation().getIsEnd() ? " (最后一个结果)" : ""));
                    
                    if (result.getTranslation().getIsEnd()) {
                        latch.countDown();
                    }
                } else if (result.isFinal()) {
                    System.out.println("最终识别结果: " + result.getPlainText());
                } else if (result.isIntermediate()) {
                    System.out.println("中间识别结果: " + result.getPlainText());
                }
            }
            
            @Override
            public void onError(String errorCode, String errorMessage) {
                System.err.println("识别失败: " + errorMessage + ", 错误码: " + errorCode);
                latch.countDown();
            }
            
            @Override
            public void onClose() {
                long endTime = System.currentTimeMillis();
                System.out.println("连接已关闭，总耗时: " + (endTime - startTime) + "ms");
                latch.countDown();
            }
        };
        
        try {
            // 开始实时语音转写
            service.startRealTimeASR(params, callback);
            
            // 等待异步识别完成
            latch.await();
        } finally {
            // 关闭连接
            service.close();
        }
    }
    
    /**
     * 读取音频文件
     * 
     * @param filePath 文件路径
     * @return 音频数据
     */
    private static byte[] readAudioFile(String filePath) {
        try {
            File audioFile = new File(filePath);
            
            if (!audioFile.exists()) {
                return null;
            }
            
            return Files.readAllBytes(Paths.get(filePath));
            
        } catch (IOException e) {
            System.err.println("读取音频文件失败: " + e.getMessage());
            return null;
        }
    }
} 